
Type.registerNamespace("SoulSolutions.Demo");

SoulSolutions.Demo.CustomInfoBox = function(element) {
    /// <summary>
    ///   The custom infobox (popup) for the map.
    ///   Supports load on demand, infinate scroll
    /// </summary>
    /// <param name="element">The div element to be made into the infobox.</param>
    SoulSolutions.Demo.CustomInfoBox.initializeBase(this, [element]); 
    
    this._service;
    this._map;
    this._centreX;
    this._centreY;
    
    this._infoBoxpanel;
    this._contentpanel;
    this._statuspanel;
    this._closeelement;
    
    this._currentpin = null;
    this._currentpinInfoBox = null;
    this._isvisible = false;
    
    this._recordsloaded = 0;
    this._totalrecords = 0;
    this._contentFetching = false;
    this._triggerContentHeight = 100;
 
    this._ScrollDelegate = null;
    this._PinClickDelegate = null;
    this._CloseDelegate = null;
}

SoulSolutions.Demo.CustomInfoBox.prototype = {

    initialize: function() {
        /// <summary>
        ///   Initialises the Control.
        /// </summary>
        
        this._infoBoxpanel = this.get_element();
        //this._map.AddControl(this._infoBoxpanel);
        
        this._closeelement = document.createElement("div");
        this._closeelement.id = "CustomInfoBoxClose"
        this._closeelement.className = "InfoBoxClose"
        this._infoBoxpanel.appendChild(this._closeelement);    
              
        this._contentpanel = document.createElement("div");
        this._contentpanel.id = "CustomInfoBoxContent"
        this._contentpanel.className = "InfoBoxContent"
        this._infoBoxpanel.appendChild(this._contentpanel);
        
        this._statuspanel = document.createElement("div");
        this._statuspanel.id = "CustomInfoBoxStatus"
        this._statuspanel.className = "InfoBoxStatus"
        this._infoBoxpanel.appendChild(this._statuspanel);
                 
        this._ScrollDelegate = Function.createDelegate(this, this._onContentScroll);
        $addHandler(this._contentpanel,"scroll",this._ScrollDelegate);
        
        this._CloseDelegate = Function.createDelegate(this, this._HidePanel);
        $addHandler(this._closeelement,"click",this._CloseDelegate);        
        
        //turn off the standard popup and attach our custom handler
        this._PinClickDelegate = Function.createDelegate(this, this._LoadInfobox);
        this._map.AttachEvent("onclick", this._PinClickDelegate);
    },
    
    NotifyDeleteAllShapes: function() {
        this._currentpin = null
        this._currentpinInfoBox = null
        this._HidePanel();
    },      
    
    _LoadInfobox: function(e) {
        /// <summary>
        ///   Receives any mouse of event from VE
        /// </summary>  
        /// <param name="e">The MapEvent object</param>         
        if (e.elementID)
        {
            var popupShape = this._map.GetShapeByID(e.elementID)
              
            //verify new pin
            if (this._currentpinInfoBox == null || popupShape.Bounds != this._currentpinInfoBox.Bounds) {
                this._HidePanel();    

                //set current pin, clear all existing data
                this._currentpinInfoBox = popupShape;
                this._recordsloaded = 0;
                this._totalrecords = 0;
                this._contentpanel.innerHTML = "";
                this._statuspanel.innerHTML = "";
                
                //get the content for the pin.
                this._GetData();
            }
            if (!this._isvisible) {
                this._isvisible = true;
                var point;
                
                //get point
                if (this._currentpinInfoBox.GetType() == VEShapeType.Pushpin) { 
                    point = this._map.LatLongToPixel(this._currentpinInfoBox.GetPoints()[0]);
                } else {

                    point = this._map.LatLongToPixel(this._currentpinInfoBox.GetIconAnchor()); 
                }
                
                var cssStyle = "infobox";
                if (point.y > this._centreY) {
                    cssStyle += "T";
                }else {
                    cssStyle += "B";
                }                
                if (point.x > this._centreX) {
                    cssStyle += "L";
                }else {
                    cssStyle += "R";
                }
                this._infoBoxpanel.className = cssStyle;
                //TODO: Sort out map offets
                this._infoBoxpanel.style.left =  point.x + "px";
                this._infoBoxpanel.style.top = point.y + "px";
                this._infoBoxpanel.style.display = "block";
            }
            return true;
        }
    },      
    
    _HidePanel: function() {
        this._infoBoxpanel.style.display = "none";
        this._isvisible = false;
    },          
    
    _onContentScroll: function() {
        if (!this._contentFetching && (this._recordsloaded < this._totalrecords) && (this._contentpanel.scrollTop + this._contentpanel.offsetHeight) > (this._contentpanel.scrollHeight - this._triggerContentHeight)) {
            this._GetData();
        }
    },

    _GetData: function() { 
           
        this._contentFetching = true;
        this._statuspanel.innerHTML = "Loading...";
        //call the web service
        this._service.GetPushPin(this._currentpinInfoBox.Bounds, this._recordsloaded, Function.createDelegate(this, this._OnContentSucceeded), Utility.OnFailed, this._currentpinInfoBox.Bounds);
    }, 
    
    _OnContentSucceeded: function(result, bounds) { 
        /// <summary>
        ///   Receive content for popup.
        /// </summary>  
        /// <param name="result">The webservice result object - JSON PinData</param>  
        this._contentFetching = false;
        //confirm the results are for the current pin
        if (this._currentpinInfoBox != null && bounds == this._currentpinInfoBox.Bounds) {     
            for (var x=0;x<result.Items.length;x++) {
                var recordItem = document.createElement("div");
                recordItem.innerHTML = result.Items[x].Title + " - " + result.Items[x].Details;
                this._contentpanel.appendChild(recordItem);
                this._recordsloaded++;
            }   
            this._statuspanel.innerHTML = this._recordsloaded + " items of " + result.TotalRecords + " loaded";
            this._totalrecords = result.TotalRecords;
        }
    },    
    
    get_Service : function() {
        return this._service;
    }, 

    set_Service : function(value) {
        this._service = value;
    },
    
    get_Map : function() {
        return this._map;
    }, 

    set_Map : function(value) {
        this._map = value;
    },        
    
    get_CentreX : function() {
        return this._centreX;
    }, 

    set_CentreX : function(value) {
        this._centreX = value;
    },
    
    get_CentreY : function() {
        return this._centreY;
    }, 

    set_CentreY : function(value) {
        this._centreY = value;
    }, 
           
    dispose: function() {
        /// <summary>
        ///   cleans up all objects. Detaches all events.
        /// </summary>
   
        $removeHandler(this._contentpanel,"scroll",this._ScrollDelegate);
        $removeHandler(this._closeelement,"click",this._CloseDelegate);
        
        this._ScrollDelegate = null;
        this._PinClickDelegate = null;
        this._CloseDelegate = null;
        
        this._contentpanel = null;
        this._statuspanel = null;
        this._closeelement = null;
        this._infoBoxpanel = null;
        SoulSolutions.Demo.CustomInfoBox.callBaseMethod(this, 'dispose');
    }    
}

SoulSolutions.Demo.CustomInfoBox.registerClass('SoulSolutions.Demo.CustomInfoBox', Sys.UI.Control);

if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();

